﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class RollCharacterAction : BaseAction {

	public TextMesh NameField;
	public TextMesh GenderField;
	public TextMesh AgeField;

	//Game Object whose collider defines the area for displaying stats
	public GameObject StatFieldArea;

	//Temporary constants for min and max random stat values
	private const float MIN_RAND_STAT = 1;
	private const float MAX_RAND_STAT = 20;

	private const string STAT_LABEL_SUFFIX = "lbl";
	private const string STAT_VALUE_SUFFIX = "val";

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}

	/// <summary>
	/// Executes the roll wife action
	/// </summary>
	public override void ExecuteAction(){
		Debug.Log ("Roll Character!");

		CharacterData charData = new CharacterData();

		charData.Age = Random.Range(12.0f, 60.0f);
		//Select a random gender
		charData.GenderType = GetRandomGender();

		string firstName;
		string lastName;
		CharacterNameLibrary.Instance.GenerateName(charData.GenderType, out firstName, out lastName);
		charData.FirstName = firstName;
		charData.LastName = lastName;

		charData.GeneticStats = CreateRandomGeneticStats();

		//TESTING
		Debug.Log ("Created " + charData.GenderType.ToString() + " Character: '" + 
		           charData.FirstName + " " + charData.LastName + 
		           "', Age: " + charData.Age);

		DisplayCharacter (charData);
	}
	

	/// <summary>
	/// Displaies the character.
	/// </summary>
	/// <param name="charData">Char data.</param>
	private void DisplayCharacter(CharacterData charData){
		//Set the data in text fields
		if(NameField != null){
			NameField.text = charData.FirstName + " " + charData.LastName;
		}
		if(GenderField != null){
			GenderField.text = charData.GenderType.ToString ();
		}
		if(AgeField != null){
			AgeField.text = ((int)charData.Age).ToString();
		}
		
		//Display the value of all genetic stats
		if(StatFieldArea != null){
			Debug.Log("Displaying Stats");

			Bounds fieldBounds = StatFieldArea.collider.bounds;
			Vector2 statFieldStart = new Vector2(fieldBounds.min.x, fieldBounds.max.y);
			Vector2 statFieldSize = new Vector2(fieldBounds.size.x, fieldBounds.size.y);
			float statFieldOffsetY = statFieldSize.y / charData.GeneticStats.NumStats;
			float valueFieldOffsetX = statFieldSize.x / 2.0f;

			GameObject textObj;
			string statName;
			int statValue;
			Transform textTransform;

			List<string> statNames = charData.GeneticStats.GetAllStatNames();
			for(int i = 0; i < statNames.Count; i++){
				statName = statNames[i];

				//Create a label field if one doesn't already exist
				if(StatFieldArea.transform.Find(statName + STAT_LABEL_SUFFIX) == null){
					//Create the label text field
					textObj = CreateStatTextField(statName + STAT_LABEL_SUFFIX, statName);
					textObj.transform.position = new Vector3(statFieldStart.x, statFieldStart.y - i * statFieldOffsetY, -2);
					textObj.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
				}

				//Create the stat value text field if one doesn't already exist
				statValue = (int)charData.GeneticStats.GetValueForStat(statName);

				textTransform = StatFieldArea.transform.Find(statName + STAT_VALUE_SUFFIX);
				if(textTransform == null){
					textObj = CreateStatTextField(statName + STAT_VALUE_SUFFIX, statValue.ToString());
				}else{
					textObj = textTransform.gameObject;
					textObj.GetComponent<TextMesh>().text = statValue.ToString();
				}

				textObj.transform.position = new Vector3(statFieldStart.x + valueFieldOffsetX, statFieldStart.y - i * statFieldOffsetY, -2);
				textObj.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
			}
		}
	}
	


	private GameObject CreateStatTextField(string objName, string text){
		GameObject textObj;
		TextMesh textMesh;
		
		textObj = new GameObject(objName);
		textObj.transform.parent = StatFieldArea.transform;
		textMesh = textObj.AddComponent<TextMesh>();
		textMesh.color = Color.black;
		textMesh.fontSize = 24;
		textMesh.text = text;
		textMesh.font = NameField.font;
		textMesh.renderer.material = textMesh.font.material;

		return textObj;
	}
	
	/// <summary>
	/// Gets a random gender.
	/// </summary>
	/// <returns>A random gender.</returns>
	private Gender GetRandomGender(){
		int rand = Random.Range (0, 2);
		if(rand == 0){
			return Gender.Male;
		}else{
			return Gender.Female;
		}
	}


	/// <summary>
	/// Creates a random set of genetic stats
	/// </summary>
	/// <returns>A random set of genetic stats</returns>
	private StatSet CreateRandomGeneticStats(){

		StatSet geneticStats = GeneticStatLibrary.Instance.CreateGeneticStatSet();
		List<string> statNames = geneticStats.GetAllStatNames();
		float randStat;

		//Select a random value for each stat
		foreach(string statName in statNames){
			randStat = Random.Range(MIN_RAND_STAT, MAX_RAND_STAT);
			geneticStats.SetValueForStat(statName, randStat);
		}

		return geneticStats;
	}
}
